package com.admin_system.controller;

import com.admin_system.entity.MergeResponse;
import com.admin_system.service.DocumentMergeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.http.ContentDisposition;
import java.net.ConnectException;
import java.nio.charset.StandardCharsets;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 该控制器实现接收前端的文件合并请求
 */
@RestController
@RequestMapping("/api/document")
@Slf4j
public class DocumentMergeController {

    @Autowired
    private DocumentMergeService documentMergeService;
    
    // 用于标记是否正在合并，保证只有一个用户可以进行合并操作
    private static volatile boolean isMerging = false;

    /**
     * 文档合并接口
     */
    @PostMapping("/merge")
    public ResponseEntity<MergeResponse> mergeDocuments(
            @RequestParam(value = "paper_files", required = false) List<MultipartFile> paperFiles,
            @RequestParam(value = "answer_files", required = false) List<MultipartFile> answerFiles,
            @RequestParam(value = "output_format", defaultValue = "auto") String outputFormat,
            @RequestParam(value = "merge_order", defaultValue = "paper-first") String mergeOrder) {
        
        log.info("接收到文档合并请求 - 试卷文件数量: {}, 答案文件数量: {}, 输出格式: {}, 合并顺序: {}", 
                paperFiles != null ? paperFiles.size() : 0, 
                answerFiles != null ? answerFiles.size() : 0, 
                outputFormat, mergeOrder);
        
        // 检查是否有其他用户正在执行合并操作
        if (isMerging) {
            log.warn("已有其他用户正在使用文档合并工具，请求被拒绝");
            MergeResponse response = new MergeResponse();
            response.setStatus("busy");
            response.setMessage("系统正在为其他用户处理合并请求，请稍后再试");
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(response);
        }
        
        // 记录文件信息
        if (paperFiles != null && !paperFiles.isEmpty()) {
            for (int i = 0; i < paperFiles.size(); i++) {
                MultipartFile file = paperFiles.get(i);
                log.info("试卷文件[{}]: 名称={}, 大小={} 字节, 内容类型={}", 
                        i, file.getOriginalFilename(), file.getSize(), file.getContentType());
            }
        }
        
        if (answerFiles != null && !answerFiles.isEmpty()) {
            for (int i = 0; i < answerFiles.size(); i++) {
                MultipartFile file = answerFiles.get(i);
                log.info("答案文件[{}]: 名称={}, 大小={} 字节, 内容类型={}", 
                        i, file.getOriginalFilename(), file.getSize(), file.getContentType());
            }
        }
        
        if ((paperFiles == null || paperFiles.isEmpty()) && (answerFiles == null || answerFiles.isEmpty())) {
            MergeResponse response = new MergeResponse();
            response.setStatus("failed");
            response.setMessage("未上传任何文件");
            log.warn("合并请求失败: 未上传任何文件");
            return ResponseEntity.badRequest().body(response);
        }
        
        // 设置合并状态为正在合并
        isMerging = true;
        try {
            try {
                MergeResponse response = documentMergeService.mergeDocuments(paperFiles, answerFiles, outputFormat, mergeOrder);
                log.info("文档合并请求处理完成 - 任务ID: {}, 状态: {}", response.getTaskId(), response.getStatus());
                return ResponseEntity.ok(response);
            } catch (Exception e) {
                log.error("文档合并请求处理失败", e);
                MergeResponse response = new MergeResponse();
                response.setStatus("failed");
                
                // 根据异常类型提供友好的错误消息
                if (e instanceof ConnectException || e.getCause() instanceof ConnectException 
                        || (e.getMessage() != null && e.getMessage().contains("Connection refused"))) {
                    response.setMessage("后台处理服务暂时不可用，请稍后再试");
                    log.error("Python服务连接失败: {}", e.getMessage());
                } else {
                    response.setMessage("文档处理过程中发生错误: " + e.getMessage());
                }
                
                return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(response);
            }
        } finally {
            // 无论成功还是失败，都需要重置合并状态
            isMerging = false;
            log.info("合并操作完成，重置合并状态");
        }
    }

    /**
     * 获取任务状态接口
     */
    @GetMapping("/task/{taskId}")
    public ResponseEntity<MergeResponse> getTaskStatus(@PathVariable String taskId) {
        log.info("获取任务状态 - 任务ID: {}", taskId);
        
        // 检查任务ID是否为空
        if (taskId == null || taskId.equals("null") || taskId.trim().isEmpty()) {
            log.warn("获取任务状态失败：任务ID为空");
            MergeResponse response = new MergeResponse();
            response.setStatus("failed");
            response.setMessage("无效的任务ID");
            return ResponseEntity.badRequest().body(response);
        }
        
        try {
            MergeResponse response = documentMergeService.getTaskStatus(taskId);
            log.info("任务状态 - ID: {}, 状态: {}, 进度: {}%, 消息: {}", 
                    taskId, response.getStatus(), response.getProgress(), response.getMessage());
            return ResponseEntity.ok(response);
        } catch (Exception e) {
            log.error("获取任务状态失败 - 任务ID: {}, 错误: {}", taskId, e.getMessage(), e);
            
            MergeResponse errorResponse = new MergeResponse();
            errorResponse.setStatus("error");
            errorResponse.setTaskId(taskId);
            
            // 根据异常类型提供友好的错误消息
            if (e instanceof ConnectException || e.getCause() instanceof ConnectException 
                    || (e.getMessage() != null && e.getMessage().contains("Connection refused"))) {
                errorResponse.setMessage("后台处理服务暂时不可用，请稍后再试");
                log.error("Python服务连接失败: {}", e.getMessage());
            } else {
                errorResponse.setMessage("获取任务状态时发生错误");
            }
            
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(errorResponse);
        }
    }

    /**
     * 下载合并文档接口
     */
    @GetMapping("/download-merged/{taskId}")
    public ResponseEntity<Resource> downloadMergedDocument(@PathVariable String taskId) {
        log.info("下载合并文档 - 任务ID: {}", taskId);
        
        // 检查任务ID是否为空
        if (taskId == null || taskId.equals("null") || taskId.trim().isEmpty()) {
            log.warn("下载合并文档失败：任务ID为空");
            return ResponseEntity.badRequest().body(null);
        }
        
        try {
            Resource resource = documentMergeService.downloadMergedDocument(taskId);
            
            // 先获取任务状态，确定文件类型和文件名
            MergeResponse taskStatus = documentMergeService.getTaskStatus(taskId);
            
            String contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE;
            String fileName = "merged_document";
            
            // 使用原始文件名(如果有的话)
            if (taskStatus.getOriginalFilename() != null && !taskStatus.getOriginalFilename().isEmpty()) {
                fileName = taskStatus.getOriginalFilename();
                log.info("使用合并文件名: {}", fileName);
            }
            
            // 根据输出路径确定文件类型和扩展名
            if (taskStatus.getOutputPath() != null) {
                String path = taskStatus.getOutputPath();
                if (path.toLowerCase().endsWith(".pdf")) {
                    contentType = MediaType.APPLICATION_PDF_VALUE;
                    if (!fileName.toLowerCase().endsWith(".pdf")) {
                        fileName += ".pdf";
                    }
                } else if (path.toLowerCase().endsWith(".docx")) {
                    contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
                    if (!fileName.toLowerCase().endsWith(".docx")) {
                        fileName += ".docx";
                    }
                }
            }
            
            log.info("准备下载文件 - 任务ID: {}, 文件名: {}, 内容类型: {}", taskId, fileName, contentType);
            
            // 确保文件名编码正确
            String encodedFileName;
            try {
                encodedFileName = java.net.URLEncoder.encode(fileName, "UTF-8")
                        .replaceAll("\\+", "%20"); // 将+替换为%20
            } catch (Exception e) {
                log.error("文件名编码失败", e);
                encodedFileName = fileName;
            }
            
            // 设置响应头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            headers.setContentDispositionFormData("attachment", encodedFileName);
            headers.setContentDisposition(ContentDisposition.attachment()
                    .filename(fileName, StandardCharsets.UTF_8)
                    .build());
            
            // 添加缓存控制头
            headers.setCacheControl("no-cache");
            headers.setPragma("no-cache");
            headers.setExpires(0);
            
            return ResponseEntity.ok()
                    .headers(headers)
                    .body(resource);
        } catch (Exception e) {
            log.error("下载合并文档失败 - 任务ID: {}", taskId, e);
            
            // 根据异常类型返回不同的友好错误信息
            HttpStatus status = HttpStatus.INTERNAL_SERVER_ERROR;
            String errorMsg = "下载文件时发生错误";
            
            if (e instanceof ConnectException || e.getCause() instanceof ConnectException 
                    || (e.getMessage() != null && e.getMessage().contains("Connection refused"))) {
                errorMsg = "后台处理服务暂时不可用，请稍后再试";
                status = HttpStatus.SERVICE_UNAVAILABLE;
                log.error("Python服务连接失败: {}", e.getMessage());
            }
            
            return ResponseEntity.status(status)
                    .body(null);
        }
    }
    
    /**
     * 检查Python服务状态
     */
    @GetMapping("/python-status")
    public ResponseEntity<?> checkPythonServiceStatus() {
        log.info("检查Python服务状态");
        try {
            return ResponseEntity.ok(documentMergeService.checkPythonServiceStatus());
        } catch (Exception e) {
            log.error("检查Python服务状态失败", e);
            
            Map<String, Object> response = new HashMap<>();
            String errorMsg = "Python服务异常";
            
            if (e instanceof ConnectException || e.getCause() instanceof ConnectException 
                    || (e.getMessage() != null && e.getMessage().contains("Connection refused"))) {
                errorMsg = "Python服务暂时不可用，请稍后再试";
                log.error("Python服务连接失败: {}", e.getMessage());
            } else {
                errorMsg += ": " + e.getMessage();
            }
            
            response.put("status", "error");
            response.put("message", errorMsg);
            
            return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
                    .body(response);
        }
    }
    
    /**
     * 测试端点：强制重启Python处理服务
     */
    @GetMapping("/restart-python")
    public ResponseEntity<String> restartPythonService() {
        log.info("尝试重启Python服务");
        try {
            // 这里不实际重启服务，只返回指令说明
            return ResponseEntity.ok("请手动重启Python服务：\n"
                    + "1. 打开命令行\n"
                    + "2. 切换到项目目录: cd " + System.getProperty("user.dir") + "\n"
                    + "3. 进入Python服务目录: cd src/main/resources/python_service\n"
                    + "4. 运行服务: python document_merge_service.py");
        } catch (Exception e) {
            log.error("生成重启指令失败", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("生成重启指令失败: " + e.getMessage());
        }
    }
    
    /**
     * 清理临时文件和过期任务
     */
    @PostMapping("/cleanup")
    public ResponseEntity<?> cleanupTempFiles() {
        log.info("请求清理临时文件和过期任务");
        try {
            Map<String, Object> result = documentMergeService.cleanupTempFiles();
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            log.error("清理临时文件失败", e);
            
            Map<String, Object> response = new HashMap<>();
            String errorMsg = "清理临时文件失败";
            
            if (e instanceof ConnectException || e.getCause() instanceof ConnectException 
                    || (e.getMessage() != null && e.getMessage().contains("Connection refused"))) {
                errorMsg = "后台清理服务暂时不可用，请稍后再试";
                log.error("Python服务连接失败: {}", e.getMessage());
            } else {
                errorMsg += ": " + e.getMessage();
            }
            
            response.put("status", "error");
            response.put("message", errorMsg);
            
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(response);
        }
    }
} 